/*
 * @(#)$Id: oal.h
 * @(#) definition of os abstract functions
 *
 * This implementation is a part of Local NGI 2.0 Framework
 * (c)  SGM/PATAC 2011
 * 3999 Longdong Avenue, Pudong Shanghai 201201, China
 * All Rights Reserved.
 */

#ifndef _C_VISOAL_H__
#define _C_VISOAL_H__

#ifdef TEST_DBG_WIN32
#include "windows.h"
#else
#include <pthread.h>
#include <semaphore.h>
#endif

#ifdef  __cplusplus
extern "C" {
#endif

#ifndef INFINITE
#define INFINITE	(0xFFFFFFFF)
#endif

typedef struct sync_object
{
#ifdef TEST_DBG_WIN32
	CRITICAL_SECTION cs;
#else
	unsigned int LockCount;			// remember the count for a same thread
	unsigned int ThreadID;
	sem_t	sem;
#endif
}
sync_object_t;

#define init_sync_object(obj)		{0}

#ifdef TEST_DBG_WIN32
#define prepare_sync_object(obj)	\
	do {	\
	InitializeCriticalSection(&((obj).cs));	\
	} while (0)
#define release_sync_object(obj)	\
	do {	\
	DeleteCriticalSection(&((obj).cs));	\
	} while (0)
#else
#define prepare_sync_object(obj)	\
	do {	\
	(obj).LockCount = 0;	\
	(obj).ThreadID = 0;	\
	sem_init(&((obj).sem), 0, 1);	\
	} while (0)
#define release_sync_object(obj)	\
	do {	\
	sem_destroy(&((obj).sem));	\
	} while (0)
#endif

typedef struct wait_object
{
#ifdef TEST_DBG_WIN32
	HANDLE hevent;
#else
	pthread_mutex_t mut;
	pthread_cond_t cond;
#endif
	void *info;
}
wait_object_t;

#define init_wait_object(obj)	{0}

#ifdef TEST_DBG_WIN32
#define prepare_wait_object(obj)	\
	do {	\
	(obj).hevent = CreateEvent(NULL, FALSE, FALSE, NULL);	\
	(obj).info = NULL;	\
	} while (0)
#define release_wait_object(obj)	\
	do {	\
	CloseHandle((obj).hevent);	\
	} while (0)
#else
#define prepare_wait_object(obj)	\
	do {	\
	pthread_cond_init(&((obj).cond), NULL);	\
	pthread_mutex_init(&((obj).mut), NULL);	\
	(obj).info = NULL;	\
	} while (0)
#define release_wait_object(obj)	\
	do {	\
	pthread_mutex_destroy(&((obj).mut));	\
	pthread_cond_destroy(&((obj).cond));	\
	} while (0)
#endif

/* public */
int wait_obj_wait(wait_object_t *wait_obj, unsigned int msec);
void wait_obj_notify(wait_object_t *wait_obj, void* info);

unsigned int get_threadid(void);
void sync_start(sync_object_t *sync_obj);
void sync_end(sync_object_t *sync_obj);

#ifdef  __cplusplus
}
#endif

#endif /* _C_VISOAL_H__ */
/* EOF */
